﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NTmdb.Net;

namespace NTmdb.TestProject
{
    /// <summary>
    ///     This is a test class for TmdbAbstractionTest and is intended
    ///     to contain all TmdbAbstractionTest Unit Tests
    /// </summary>
    [TestClass]
    public class TmdbAbstractionTest
    {
        #region Properties

        /// <summary>
        ///     Your TMDb API key.
        /// </summary>
        private const String ApiKey = "ba9a4d5a02b4438300a712d31316a3ff";

        /// <summary>
        ///     The TMDb session ID of your account.
        /// </summary>
        private const String SessionId = "8958bf504776aa49f670af8b22c18a26ee05a580";

        /// <summary>
        ///     The ID of your TMDb account.
        /// </summary>
        private const Int32 AccountId = 5976610;

        /// <summary>
        ///     Gets or sets a instance of the test target.
        /// </summary>
        /// <value>A instance of the test target.</value>
        private static TmdbAbstraction Target { get; set; }

        #endregion Properties

        /// <summary>
        ///     Creates a new instance of the API Wrapper.
        /// </summary>
        /// <param name="testContext"></param>
        [ClassInitialize]
        public static void MyClassInitialize( TestContext testContext )
        {
            var apiWrapper = new ApiWrapper
                {
                    ApiClient = new ApiClientNet()
                };
            var config = new ApiConfiguration();
            config.RestoreDefaultValues( ApiKey );
            apiWrapper.ApiConfiguration = config;
            Target = new TmdbAbstraction( apiWrapper )
                {
                    ThrowException = true
                };
        }

        /// <summary>
        ///     A test for TmdbAbstraction Constructor
        /// </summary>
        [TestMethod]
        public void TmdbAbstractionConstructorTest()
        {
            IApiWrapper apiWrapper = new ApiWrapper();
            var maxConcurrentConnections = new Random().Next( 1, Int32.MaxValue );
            var target = new TmdbAbstraction( apiWrapper, maxConcurrentConnections );
            Assert.AreSame( target.ApiWrapper, apiWrapper );
        }

        /// <summary>
        ///     A test for TmdbAbstraction Constructor
        /// </summary>
        [TestMethod]
        [ExpectedException( typeof ( ArgumentException ) )]
        public void TmdbAbstractionConstructorTest1()
        {
            IApiWrapper apiWrapper = new ApiWrapper();
            var target = new TmdbAbstraction( apiWrapper, 0 );
        }

        #region Configuration

        /// <summary>
        ///     A test for GetConfigurationAsync
        /// </summary>
        [TestMethod]
        public async Task GetConfigurationAsyncTest()
        {
            var actual = await Target.GetConfigurationAsync();
            Assert.IsTrue( actual.ImageConfiguration.LogoSizes.Any() );
            Assert.IsTrue( actual.ChangeKeys.Any() );
            Assert.IsFalse( String.IsNullOrEmpty( actual.ImageConfiguration.BaseUrl ) );
            Assert.AreEqual( actual.ImageConfiguration.BaseUrl, Target.TmdbConfiguration.ImageConfiguration.BaseUrl );
        }

        #endregion Configuration

        #region Authentication

        /// <summary>
        ///     A test for GetAuthenticationTokenAsync
        /// </summary>
        [TestMethod]
        public async Task GetAuthenticationTokenAsyncTest()
        {
            var actual = await Target.GetAuthenticationTokenAsync();
            Assert.IsFalse( String.IsNullOrEmpty( actual.Token ) );
            Assert.IsTrue( actual.Success );
            Assert.AreEqual(actual.Token, Target.AuthenticationToken);
        }

        /// <summary>
        ///     A test for GetSessionAsync
        /// </summary>
        [TestMethod]
        [ExpectedException( typeof ( TmdbException ) )]
        public async Task GetSessionAsyncTest401()
        {
            var token = await Target.GetAuthenticationTokenAsync();
            Assert.IsTrue( token.Success, "GetAuthenticationTokenAsync failed!" );

            var actual = await Target.GetSessionAsync( token.Token );
        }

        /// <summary>
        ///     A test for GetSessionAsync
        /// </summary>
        //[TestMethod]
        public async Task GetSessionAsyncTest()
        {
            var token = await Target.GetAuthenticationTokenAsync();
            Assert.IsTrue( token.Success, "GetAuthenticationTokenAsync failed!" );

            //Before you can get a valid session ID, you must accept the authentication token on the TMDb site.
            var urlToOpen = String.Format( "https://www.themoviedb.org/authenticate/{0}", token.Token );
            Process.Start( urlToOpen );

            var actual = await Target.GetSessionAsync( token.Token );
            Assert.IsFalse( String.IsNullOrEmpty( actual.SessionId ) );
            Assert.IsTrue( actual.Success );
            Assert.AreEqual(actual.SessionId, Target.SessionId);
        }

        /// <summary>
        ///     A test for GetSessionAsync
        /// </summary>
        //[TestMethod]
        public async Task GetSessionAsyncTest1()
        {
            var token = await Target.GetAuthenticationTokenAsync();
            Assert.IsTrue(token.Success, "GetAuthenticationTokenAsync failed!");

            //Before you can get a valid session ID, you must accept the authentication token on the TMDb site.
            var urlToOpen = String.Format("https://www.themoviedb.org/authenticate/{0}", token.Token);
            Process.Start(urlToOpen);

            var actual = await Target.GetSessionAsync();
            Assert.IsFalse(String.IsNullOrEmpty(actual.SessionId));
            Assert.IsTrue(actual.Success);

            Assert.AreEqual( actual.SessionId, Target.SessionId );
        }

        /// <summary>
        ///     A test for GetGuestSessionAsync
        /// </summary>
        [TestMethod]
        public async Task GetGuestSessionAsyncTest()
        {
            var actual = await Target.GetGuestSessionAsync();
            Assert.IsFalse( String.IsNullOrEmpty( actual.GuestSessionId ) );
            Assert.IsTrue( actual.Success );
        }

        /// <summary>
        ///     A test for GetSessionWithoutAuthenticationTokenAsync
        /// </summary>
        [TestMethod]
        public async Task GetSessionWithoutAuthenticationTokenAsyncTest()
        {
            var actual = await Target.GetSessionWithoutAuthenticationTokenAsync( token =>
                {
                    Assert.IsTrue( token.Success );
                    return false;
                } );
            Assert.IsNull( actual );
        }

        /// <summary>
        ///     A test for GetSessionWithoutAuthenticationTokenAsync
        /// </summary>
        //[TestMethod]
        public async Task GetSessionWithoutAuthenticationTokenAsyncTest1()
        {
            var actual = await Target.GetSessionWithoutAuthenticationTokenAsync(token =>
            {
                Assert.IsTrue(token.Success);
                var url = String.Format( "https://www.themoviedb.org/authenticate/{0}", token.Token );
                Process.Start( url );

                //Break here and accept the token!
                return true;
            });
            Assert.IsTrue( actual.Success, "Have you accept the token?" );
        }

        #endregion Authentication

        #region Account

        /// <summary>
        ///     A test for GetAccountAsync
        /// </summary>
        [TestMethod]
        public async Task GetAccountAsyncTest()
        {
            Target.SessionId = SessionId;
            Target.AccountId = 0;
            var actual = await Target.GetAccountAsync();
            Assert.IsTrue( actual.Id > 0 );
            Assert.AreEqual( actual.Id, Target.AccountId );
        }

        /// <summary>
        ///     A test for GetAccountListsAsync
        /// </summary>
        [TestMethod]
        public async Task GetAccountListsAsyncTest()
        {
            Target.SessionId = SessionId;
            Target.AccountId = AccountId;
            var actual = await Target.GetAccountListsAsync();
            Assert.IsTrue( actual.TotalResults > 0 );
        }

        /// <summary>
        ///     A test for SetFavoriteAsync
        /// </summary>
        [TestMethod]
        public async Task SetFavoriteAsyncTest()
        {
            Target.SessionId = SessionId;
            Target.AccountId = AccountId;
            var actual = await Target.SetFavoriteAsync( new TmdbFavoriteRequest
                {
                    AddToFavorite = true,
                    Id = 550
                } );
            Assert.IsFalse( String.IsNullOrEmpty( actual.StatusMessage ) );
        }

        /// <summary>
        ///     A test for SetWatchListAsync
        /// </summary>
        [TestMethod]
        public async Task SetWatchListAsyncTest()
        {
            Target.SessionId = SessionId;
            Target.AccountId = AccountId;
            var actual = await Target.SetWatchListAsync( new TmdbWatchListRequest
                {
                    Id = 550,
                    AddToWatchList = true
                } );
            Assert.IsFalse( String.IsNullOrEmpty( actual.StatusMessage ) );
        }

        /// <summary>
        ///     A test for GetAccountFavoriteMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetAccountFavoriteMoviesAsyncTest()
        {
            Target.SessionId = SessionId;
            Target.AccountId = AccountId;
            var actual = await Target.GetAccountFavoriteMoviesAsync();
            Assert.IsTrue( actual.TotalResults > 0 );
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetAccountRatedMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetAccountRatedMoviesAsyncTest()
        {
            Target.SessionId = SessionId;
            Target.AccountId = AccountId;
            var actual = await Target.GetAccountRatedMoviesAsync();
            Assert.IsTrue( actual.TotalResults > 0 );
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetAccountWatchListAsync
        /// </summary>
        [TestMethod]
        public async Task GetAccountWatchListAsyncTest()
        {
            Target.SessionId = SessionId;
            Target.AccountId = AccountId;
            var actual = await Target.GetAccountWatchListAsync();
            Assert.IsTrue( actual.TotalResults > 0 );
            Assert.IsTrue( actual.Movies.Any() );
        }

        #endregion Account

        #region Movie

        /// <summary>
        ///     A test for GetMovieAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieAsyncTest()
        {
            var actual = await Target.GetMovieAsync( 550, TmdbMovieMethod.Lists );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetAlternativeMovieTitlesAsync
        /// </summary>
        [TestMethod]
        public async Task GetAlternativeMovieTitlesAsyncTest()
        {
            var actual = await Target.GetAlternativeMovieTitlesAsync( 550 );
            Assert.IsTrue( actual.Titles.Any() );
        }

        /// <summary>
        ///     A test for GetMovieCastAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieCastAsyncTest()
        {
            var actual = await Target.GetMovieCastAsync( 550 );
            Assert.IsTrue( actual.Cast.Any() );
            Assert.IsTrue( actual.Crew.Any() );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetMovieImagesAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieImagesAsyncTest()
        {
            var actual = await Target.GetMovieImagesAsync( 550 );
            Assert.IsTrue( actual.Backdrops.Any() );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetMovieKeywordsAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieKeywordsAsyncTest()
        {
            var actual = await Target.GetMovieKeywordsAsync( 550 );
            Assert.IsTrue( actual.Keywords.Any() );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetMovieReleasesAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieReleasesAsyncTest()
        {
            var actual = await Target.GetMovieReleasesAsync( 550 );
            Assert.IsTrue( actual.Releases.Any() );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetMovieTrailersAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieTrailersAsyncTest()
        {
            var actual = await Target.GetMovieTrailersAsync( 550 );
            Assert.IsTrue( actual.Youtube.Any() );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetMovieTranslationsAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieTranslationsAsyncTest()
        {
            var actual = await Target.GetMovieTranslationsAsync( 550 );
            Assert.IsTrue( actual.Translations.Any() );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetSimilarMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetSimilarMoviesAsyncTest()
        {
            var actual = await Target.GetSimilarMoviesAsync( 550 );
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetMovieReviewsAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieReviewsAsyncTest()
        {
            var actual = await Target.GetMovieReviewsAsync( 49026 );
            Assert.IsTrue( actual.Reviews.Any() );
            Assert.AreEqual( 49026, actual.Id );
        }

        /// <summary>
        ///     A test for GetMovieListsAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieListsAsyncTest()
        {
            var actual = await Target.GetMovieListsAsync( 550 );
            Assert.IsTrue( actual.MovieLists.Any() );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for GetMovieChangesAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieChangesAsyncTest()
        {
            var actual = await Target.GetMovieChangesAsync( 550 );
        }

        /// <summary>
        ///     A test for GetLatestMovieAsync
        /// </summary>
        [TestMethod]
        public async Task GetLatestMovieAsyncTest()
        {
            var actual = await Target.GetLatestMovieAsync();
            Assert.IsTrue( actual.Id > 0 );
        }

        /// <summary>
        ///     A test for GetUpcomingMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetUpcomingMoviesAsyncTest()
        {
            var actual = await Target.GetUpcomingMoviesAsync();
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetNowPlayingmoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetNowPlayingmoviesAsyncTest()
        {
            var actual = await Target.GetNowPlayingmoviesAsync();
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetPopularMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetPopularMoviesAsyncTest()
        {
            var actual = await Target.GetPopularMoviesAsync();
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetTopRatedMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetTopRatedMoviesAsyncTest()
        {
            var actual = await Target.GetTopRatedMoviesAsync();
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetMovieAccountStateAsync
        /// </summary>
        [TestMethod]
        public async Task GetMovieAccountStateAsyncTest()
        {
            Target.AccountId = AccountId;
            var actual = await Target.GetMovieAccountStateAsync( 550 );
            Assert.AreEqual( 550, actual.Id );
        }

        /// <summary>
        ///     A test for RateMovieAsync
        /// </summary>
        [TestMethod]
        public async Task RateMovieAsyncTest()
        {
            Target.AccountId = AccountId;
            Target.SessionId = SessionId;
            var actual = await Target.RateMovieAsync( 550, 9.5 );
            Assert.IsFalse( String.IsNullOrEmpty( actual.StatusMessage ) );
        }

        #endregion Movie

        #region Collection

        /// <summary>
        ///     A test for GetCollectionAsync
        /// </summary>
        [TestMethod]
        public async Task GetCollectionAsyncTest()
        {
            var actual = await Target.GetCollectionAsync( 119, TmdbCollectionMethod.Images );
            Assert.AreEqual( 119, actual.Id );
        }

        /// <summary>
        ///     A test for GetCollectionImagesAsync
        /// </summary>
        [TestMethod]
        public async Task GetCollectionImagesAsyncTest()
        {
            var actual = await Target.GetCollectionImagesAsync( 119 );
            Assert.IsTrue( actual.Backdrops.Any() );
        }

        #endregion Collection

        #region People

        /// <summary>
        ///     A test for GetPersonAsync
        /// </summary>
        [TestMethod]
        public async Task GetPersonAsyncTest()
        {
            var actual = await Target.GetPersonAsync( 54693 );
            Assert.AreEqual( 54693, actual.Id );
        }

        /// <summary>
        ///     A test for GetPersonCreditsAsync
        /// </summary>
        [TestMethod]
        public async Task GetPersonCreditsAsyncTest()
        {
            var actual = await Target.GetPersonCreditsAsync( 54693 );
            Assert.IsTrue( actual.Cast.Any() );
        }

        /// <summary>
        ///     A test for GetPersonImageAsync
        /// </summary>
        [TestMethod]
        public async Task GetPersonImageAsyncTest()
        {
            var actual = await Target.GetPersonImageAsync( 54693 );
            Assert.IsTrue( actual.Images.Any() );
        }

        /// <summary>
        ///     A test for GetPersonChangesAsync
        /// </summary>
        [TestMethod]
        public async Task GetPersonChangesAsyncTest()
        {
            var actual = await Target.GetPersonChangesAsync( 54693 );
        }

        /// <summary>
        ///     A test for GetPopularPeopleAsync
        /// </summary>
        [TestMethod]
        public async Task GetPopularPersonsAsyncTest()
        {
            var actual = await Target.GetPopularPeopleAsync();
            Assert.IsTrue( actual.People.Any() );
        }

        /// <summary>
        ///     A test for GetLatestPersonAsync
        /// </summary>
        [TestMethod]
        public async Task GetLatestPersonAsyncTest()
        {
            var actual = await Target.GetLatestPersonAsync();
            Assert.IsTrue( actual.Id > 0 );
        }

        #endregion People

        #region Lists

        /// <summary>
        ///     A test for GetListAsync
        /// </summary>
        [TestMethod]
        public async Task GetListAsyncTest()
        {
            var actual = await Target.GetListAsync( "509ec17b19c2950a0600050d" );
            Assert.AreEqual( "509ec17b19c2950a0600050d", actual.Id );
        }

        /// <summary>
        ///     A test for GetListStateAsync
        /// </summary>
        [TestMethod]
        public async Task GetListStateAsyncTest()
        {
            var actual = await Target.GetListStateAsync( "509ec17b19c2950a0600050d", 550 );
            Assert.AreEqual( "509ec17b19c2950a0600050d", actual.Id );
        }

        /// <summary>
        ///     A test for CreateMovieListAsync
        /// </summary>
        [TestMethod]
        public async Task CreateMovieListAsyncTest()
        {
            Target.SessionId = SessionId;
            var actual = await Target.CreateMovieListAsync( new TmdbCreateMovieListRequest
                {
                    Name = Guid.NewGuid().ToString(),
                    Description = Guid.NewGuid().ToString(),
                    Language = "EN"
                } );
            Assert.IsFalse( String.IsNullOrEmpty( actual.ListId ) );
        }

        /// <summary>
        ///     A test for AddItemToListAsync
        /// </summary>
        [TestMethod]
        public async Task AddItemToListAsyncTest()
        {
            try
            {
                Target.SessionId = SessionId;
                var actual = await Target.AddItemToListAsync( "51e7e9b19a12187de1f04aff", 550 );
                Assert.IsTrue( actual.StatusCode > 0 );
            }
            catch ( TmdbException ex )
           {
                //The movie is already present in the list with the specified id
                Assert.IsTrue( ex.InnerException is System.Net.WebException );
                Assert.IsTrue( ex.InnerException.Message.Contains( "403" ) );
            }
        }

        /// <summary>
        ///     A test for RemoveItemFromListAsync
        /// </summary>
        [TestMethod]
        public async Task RemoveItemFromListAsyncTest()
        {
            Target.SessionId = SessionId;
            var actual = await Target.RemoveItemFromListAsync( "51ce03473bd4c03f380c6798", 550 );
            Assert.IsTrue( actual.StatusCode > 0 );
        }

        /// <summary>
        ///     A test for DeleteListAsync
        /// </summary>
        [TestMethod]
        public async Task DeleteListAsyncTest()
        {
            Target.SessionId = SessionId;
            var lists = await Target.GetAccountListsAsync();
            Assert.IsTrue( lists.MovieLists.Any(), "Your account doesn't have any lists." );

            var actual = await Target.DeleteListAsync( lists.MovieLists.First().Id );
            Assert.IsTrue( actual.StatusCode > 0 );
        }

        #endregion Lists

        #region Companies

        /// <summary>
        ///     A test for GetCompanyAsync
        /// </summary>
        [TestMethod]
        public async Task GetCompanyAsyncTest()
        {
            var actual = await Target.GetCompanyAsync( 4209, TmdbCompanyMethod.All );
            Assert.AreEqual( 4209, actual.Id );
            Assert.IsTrue( actual.Movies.Movies.Any() );
        }

        /// <summary>
        ///     A test for GetCompanyMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetCompanyMoviesAsyncTest()
        {
            var actual = await Target.GetCompanyMoviesAsync( 4209 );
            Assert.IsTrue( actual.Movies.Any() );
        }

        #endregion Companies

        #region Genres

        /// <summary>
        ///     A test for GetGenresAsync
        /// </summary>
        [TestMethod]
        public async Task GetGenresAsyncTest()
        {
            var genres = await Target.GetGenresAsync();
            Assert.IsTrue( genres.Genres.Any() );
        }

        /// <summary>
        ///     A test for GetGenreMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetGenreMoviesAsyncTest()
        {
            var actual = await Target.GetGenreMoviesAsync( 16 );
            Assert.IsTrue( actual.Movies.Any() );
        }

        #endregion Genres

        #region Keywords

        /// <summary>
        ///     A test for GetKeywordAsync
        /// </summary>
        [TestMethod]
        public async Task GetKeywordAsyncTest()
        {
            var actual = await Target.GetKeywordAsync( 158774 );
            Assert.AreEqual( 158774, actual.Id );
        }

        /// <summary>
        ///     A test for GetKeywordMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetKeywordMoviesAsyncTest()
        {
            var actual = await Target.GetKeywordMoviesAsync( 158774 );
            Assert.IsTrue( actual.Movies.Any() );
        }

        #endregion Keywords

        #region Discover

        /// <summary>
        ///     A test for DiscoverMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task DiscoverMoviesAsyncTest()
        {
            var actual = await Target.DiscoverMoviesAsync( filter: new DisoveryFilter
                {
                    GenreFilter = new GenreFilter
                        {
                            Genres = new List<Int32>
                                {
                                    28,
                                    16
                                },
                            Operator = TmdbFilterOperator.And
                        }
                } );
            Assert.IsTrue( actual.Movies.Any() );
        }

        #endregion Discover

        #region Search

        /// <summary>
        ///     A test for SearchMovieAsync
        /// </summary>
        [TestMethod]
        public async Task SearchMovieAsyncTest()
        {
            var actual = await Target.SearchMovieAsync( "Lord of the rings" );
            Assert.IsTrue( actual.Movies.Any() );
        }

        /// <summary>
        ///     A test for SearchMovieCollectionAsync
        /// </summary>
        [TestMethod]
        public async Task SearchMovieCollectionAsyncTest()
        {
            var actual = await Target.SearchMovieCollectionAsync( "Matrix" );
            Assert.IsTrue( actual.MovieCollections.Any() );
        }

        /// <summary>
        ///     A test for SearchPersonAsync
        /// </summary>
        [TestMethod]
        public async Task SearchPersonAsyncTest()
        {
            var actual = await Target.SearchPersonAsync( "Stone" );
            Assert.IsTrue( actual.People.Any() );
        }

        /// <summary>
        ///     A test for SearchListAsync
        /// </summary>
        [TestMethod]
        public async Task SearchListAsyncTest()
        {
            var actual = await Target.SearchListAsync( "Oscars" );
            Assert.IsTrue( actual.MovieLists.Any() );
        }

        /// <summary>
        ///     A test for SearchCompanyAsync
        /// </summary>
        [TestMethod]
        public async Task SearchCompanyAsyncTest()
        {
            var actual = await Target.SearchCompanyAsync( "Pictures" );
            Assert.IsTrue( actual.Companies.Any() );
        }

        /// <summary>
        ///     A test for SearchKeywordAsync
        /// </summary>
        [TestMethod]
        public async Task SearchKeywordAsyncTest()
        {
            var actual = await Target.SearchKeywordAsync( "Action" );
            Assert.IsTrue( actual.Keywords.Any() );
        }

        #endregion Search

        #region Reviews

        /// <summary>
        ///     A test for GetReviewAsync
        /// </summary>
        [TestMethod]
        public async Task GetReviewAsyncTest()
        {
            var actual = await Target.GetReviewAsync( "51cfc4bc760ee35b10356e07" );
            Assert.AreEqual( "51cfc4bc760ee35b10356e07", actual.Id );
        }

        #endregion Reviews

        #region Changes

        /// <summary>
        ///     A test for GetChangedMoviesAsync
        /// </summary>
        [TestMethod]
        public async Task GetChangedMoviesAsyncTest()
        {
            var actual = await Target.GetChangedMoviesAsync();
            Assert.IsTrue( actual.TotalResults > 0 );
        }

        /// <summary>
        ///     A test for GetChangedPeopleAsync
        /// </summary>
        [TestMethod]
        public async Task GetChangedPeopleAsyncTest()
        {
            var actual = await Target.GetChangedPeopleAsync();
            Assert.IsTrue( actual.TotalResults > 0 );
        }

        #endregion Changes

        #region Jobs

        /// <summary>
        ///     A test for GetJobsAsync
        /// </summary>
        [TestMethod]
        public async Task GetJobsAsyncTest()
        {
            var actual = await Target.GetJobsAsync();
            Assert.IsTrue( actual.Departments.Any() );
        }

        #endregion Jobs

        #region Images
        /// <summary>
        ///     A Test for DownloadImageAsync
        /// </summary>
        public async Task DownloadImageAsyncTest()
        {
            await Target.GetConfigurationAsync();
            var movie = await Target.GetMovieAsync(550);

            var filePath = movie.PosterPath;
            var size = Target.TmdbConfiguration.ImageConfiguration.PosterSizes.Last();
            var fileName = Guid.NewGuid().ToString() + ".jpg";

            var actual = await Target.DownloadImageAsync(filePath, fileName, size);
            Assert.IsTrue(File.Exists(fileName));
            Assert.AreEqual(filePath, actual);
        }

        /// <summary>
        ///     A Test for GetImageAsync
        /// </summary>
        public async Task GetImageAsyncTest()
        {
            await Target.GetConfigurationAsync();
            var movie = await Target.GetMovieAsync(550);

            var filePath = movie.PosterPath;
            var size = Target.TmdbConfiguration.ImageConfiguration.PosterSizes.Last();
            var fileName = Guid.NewGuid().ToString() + ".jpg";

            var actual = await Target.GetImageAsync(filePath, fileName, size);
            Assert.IsTrue(File.Exists(fileName));
            Assert.IsTrue( actual.Length > 0 );
        }

        /// <summary>
        ///     A Test for GetImageUrl
        /// </summary>
        public async Task GetImageUrlTest()
        {
            await Target.GetConfigurationAsync();
            var movie = await Target.GetMovieAsync(550);

            var filePath = movie.PosterPath;
            var size = Target.TmdbConfiguration.ImageConfiguration.PosterSizes.First();

            Target.ApiWrapper.ApiConfiguration.UseSecureConnection = false;
            var actual = Target.GetImageUrl(filePath, size);
            Assert.AreEqual(String.Format("{0}/{1}/{2}", Target.TmdbConfiguration.ImageConfiguration.BaseUrl, size, filePath), actual);
        }

        /// <summary>
        ///     A Test for GetImageUrl
        /// </summary>
        public async Task GetImageUrlTest1()
        {
            await Target.GetConfigurationAsync();
            var movie = await Target.GetMovieAsync(550);

            var filePath = movie.PosterPath;

            Target.ApiWrapper.ApiConfiguration.UseSecureConnection = false;
            var actual = Target.GetImageUrl(filePath);
            Assert.AreEqual(String.Format("{0}/{1}/{2}", Target.TmdbConfiguration.ImageConfiguration.BaseUrl, Target.ApiWrapper.ApiConfiguration.OriginalImageSizeValue, filePath), actual);
        }

        /// <summary>
        ///     A Test for GetImageUrl
        /// </summary>
        public async Task GetImageUrlTest2()
        {
            await Target.GetConfigurationAsync();
            var movie = await Target.GetMovieAsync(550);

            var filePath = movie.PosterPath;
            var size = Target.TmdbConfiguration.ImageConfiguration.PosterSizes.First();

            Target.ApiWrapper.ApiConfiguration.UseSecureConnection = true;
            var actual = Target.GetImageUrl(filePath, size);
            Assert.AreEqual(String.Format("{0}/{1}/{2}", Target.TmdbConfiguration.ImageConfiguration.SecureBaseUrl, size, filePath), actual);
        }

        /// <summary>
        ///     A Test for GetImageUrl
        /// </summary>
        public async Task GetImageUrlTest3()
        {
            await Target.GetConfigurationAsync();
            var movie = await Target.GetMovieAsync(550);

            var filePath = movie.PosterPath;

            Target.ApiWrapper.ApiConfiguration.UseSecureConnection = true;
            var actual = Target.GetImageUrl(filePath);
            Assert.AreEqual(String.Format("{0}/{1}/{2}", Target.TmdbConfiguration.ImageConfiguration.SecureBaseUrl, Target.ApiWrapper.ApiConfiguration.OriginalImageSizeValue, filePath), actual);
        }
        #endregion

        #region Others

        /// <summary>
        ///     A test for AccountId
        /// </summary>
        [TestMethod]
        public void AccountIdTest()
        {
            var target = new TmdbAbstraction( new ApiWrapper(), 20 );
            var expected = new Random().Next( 0, Int32.MaxValue );
            target.AccountId = expected;
            var actual = target.AccountId;
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///     A test for ApiWrapper
        /// </summary>
        [TestMethod]
        public void ApiWrapperTest()
        {
            var target = new TmdbAbstraction( new ApiWrapper(), 20 );
            var expected = new ApiWrapper();
            target.ApiWrapper = expected;
            var actual = target.ApiWrapper;
            Assert.AreSame( expected, actual );
        }

        /// <summary>
        ///     A test for IncludeAdultMovies
        /// </summary>
        [TestMethod]
        public void IncludeAdultMoviesTest()
        {
            var target = new TmdbAbstraction( new ApiWrapper(), 20 );
            var expected = new Random().Next( 0, Int32.MaxValue ) % 2 == 0;
            target.IncludeAdultMovies = expected;
            var actual = target.IncludeAdultMovies;
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///     A test for Iso639_1LanguageCode
        /// </summary>
        [TestMethod]
        public void Iso639_1LanguageCodeTest()
        {
            var target = new TmdbAbstraction( new ApiWrapper(), 20 );
            var expected = Guid.NewGuid().ToString();
            target.Iso639_1LanguageCode = expected;
            var actual = target.Iso639_1LanguageCode;
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///     A test for SessionId
        /// </summary>
        [TestMethod]
        public void SessionIdTest()
        {
            var target = new TmdbAbstraction( new ApiWrapper(), 20 );
            var expected = Guid.NewGuid().ToString();
            target.SessionId = expected;
            var actual = target.SessionId;
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///     A test for AuthenticationToken
        /// </summary>
        [TestMethod]
        public void AuthenticationTokenTest()
        {
            var target = new TmdbAbstraction(new ApiWrapper(), 20);
            var expected = Guid.NewGuid().ToString();
            target.AuthenticationToken = expected;
            var actual = target.AuthenticationToken;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///     A test for ThrowException
        /// </summary>
        [TestMethod]
        public void ThrowExceptionTest()
        {
            var target = new TmdbAbstraction( new ApiWrapper(), 20 );
            var expected = new Random().Next( 0, Int32.MaxValue ) % 2 == 0;
            target.ThrowException = expected;
            var actual = target.ThrowException;
            Assert.AreEqual( expected, actual );
        }

        /// <summary>
        ///     A test for TmdbConfiguration
        /// </summary>
        [TestMethod]
        public void TmdbConfigurationTest()
        {
            var target = new TmdbAbstraction( new ApiWrapper(), 20 );
            var expected = new TmdbConfiguration();
            target.TmdbConfiguration = expected;
            var actual = target.TmdbConfiguration;
            Assert.AreSame( expected, actual );
        }

        #endregion Others
    }
}